package com.ruoyi.lvlian.service.impl;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.MD5Utils;
import com.ruoyi.common.core.utils.PhoneNumberValidator;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.lvlian.controller.DriverInfoController;
import com.ruoyi.lvlian.domain.*;
import com.ruoyi.lvlian.dto.DriverInfoDto;
import com.ruoyi.lvlian.mapper.VehicleInfoMapper;
import com.ruoyi.lvlian.util.ExcelUtil;
import com.ruoyi.lvlian.vo.DriverInfoVo;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.lvlian.mapper.DriverInfoMapper;
import com.ruoyi.lvlian.service.IDriverInfoService;
import org.springframework.web.multipart.MultipartFile;

/**
 * 司机信息Service业务层处理
 *
 * @author liyuxi
 * @date 2024-06-06
 */
@Service
public class DriverInfoServiceImpl implements IDriverInfoService {
    private static final Logger log = LoggerFactory.getLogger(DriverInfoController.class);
    @Autowired
    private RedisService redisService;

    @Autowired
    private DriverInfoMapper driverInfoMapper;
    @Autowired
    private VehicleInfoMapper vehicleInfoMapper;



    /**
     * 查询司机信息
     *
     * @param id 司机信息主键
     * @return 司机信息
     */
    @Override
    public DriverInfoVo selectDriverInfoById(String id) {
        return driverInfoMapper.selectDriverInfoById(id);
    }

    /**
     * 查询司机信息列表
     *
     * @param driverInfo 司机信息
     * @return 司机信息
     */
    @Override
    public List<DriverInfoVo> selectDriverInfoList(DriverInfoDto driverInfo) {
        return driverInfoMapper.selectDriverInfoList(driverInfo);
    }

    /**
     * 新增司机信息
     *
     * @param driverInfo 司机信息
     * @return 结果
     */
    @Override
    public int insertDriverInfo(DriverInfo driverInfo) {
        driverInfo.setCreateUser(SecurityUtils.getUsername());
        driverInfo.setCreateDate(DateUtils.getCurrentTime());
        driverInfo.setViewFlag(true);
//司机的号码 和登录人的号码 是一样的
        LoginUser loginUser = SecurityUtils.getLoginUser();

        if (loginUser != null && StringUtils.isNotEmpty(loginUser.getSysUser().getPhonenumber()) && StringUtils.isEmpty(driverInfo.getPhoneNo())) {
            driverInfo.setPhoneNo(loginUser.getSysUser().getPhonenumber());
        }


        driverInfo.setDataSource("实时物流小程序");
        driverInfo.setDataStatus("待审批");
        driverInfo.setId(MD5Utils.md5(driverInfo.getLicenseNo() + driverInfo.getPhoneNo() + driverInfo.getDataSource()));

        SysUser sysUser = driverInfoMapper.querySysUserByPhone(driverInfo);
        if (sysUser != null && (StringUtils.isEmpty(sysUser.getUserName()) || PhoneNumberValidator.isValidPhoneNumber(sysUser.getPhonenumber()))) {
            driverInfoMapper.updateSysUser(driverInfo);
        }

        return driverInfoMapper.insertDriverInfo(driverInfo);
    }

    /**
     * 修改司机信息
     *
     * @param driverInfo 司机信息
     * @return 结果
     */
    @Override
    public int updateDriverInfo(DriverInfo driverInfo) {
        if (StringUtils.isEmpty(driverInfo.getPhoneNo())) {
            return driverInfoMapper.updateDriverInfoById(driverInfo);
        }

        String captcha = redisService.getCacheObject(driverInfo.getPhoneNo());


        if (driverInfo.getSmsCode() != null && !driverInfo.getSmsCode().equalsIgnoreCase(captcha)) {
            log.error("提交的验证码 ： " + driverInfo.getSmsCode() + "验证码错误  ，redis缓存验证码：==" + captcha);
            throw new CaptchaException(driverInfo.getSmsCode() + ":验证码错误");
        }

        DriverInfoVo driverByPhone = driverInfoMapper.getPureDriverByPhone(driverInfo.getPhoneNo());


        int updateResult = 0;
        if (driverByPhone == null || driverInfo.getDriverLicenseImg() == null) {//        数据库里面不存在 就插入

            driverInfo.setId(MD5Utils.md5(driverInfo.getLicenseNo() + driverInfo.getPhoneNo() + driverInfo.getDataSource()));

            updateResult = this.insertDriverInfo(driverInfo);
        } else {
            updateResult = driverInfoMapper.updateDriverInfo(driverInfo);
        }

//        不删 让他存在5分钟内 都有效
//        redisService.deleteObject(driverInfo.getPhoneNo());
        return updateResult;


    }

    /**
     * 批量删除司机信息
     *
     * @param ids 需要删除的司机信息主键
     * @return 结果
     */
    @Override
    public int deleteDriverInfoByIds(String[] ids) {
        return driverInfoMapper.deleteDriverInfoByIds(ids);
    }

    /**
     * 删除司机信息信息
     *
     * @param id 司机信息主键
     * @return 结果
     */
    @Override
    public int deleteDriverInfoById(String id) {
        return driverInfoMapper.deleteDriverInfoById(id);
    }

    @Override
    public DriverInfoVo getDriverByPhone(String phone, String dataSource ) {

                if( StringUtils.isEmpty(dataSource)){
                    dataSource="小程序";
                }
        DriverInfoVo vo = driverInfoMapper.getDriverByPhone(phone ,dataSource);
        if(null == vo){
            return null;
        }
        DriverInfo driverInfo = new DriverInfo();
        driverInfo.setPhoneNo(phone);
        driverInfo.setName(vo.getName());
        driverInfo.setLicenseNo(vo.getLicenseNo());

        SysUser sysUser = driverInfoMapper.querySysUserByPhone(vo);
        if (sysUser != null && (StringUtils.isEmpty(sysUser.getUserName()) || PhoneNumberValidator.isValidPhoneNumber(sysUser.getPhonenumber()))) {
            driverInfoMapper.updateSysUser(driverInfo);
            vo = driverInfoMapper.getDriverByPhone(phone,dataSource);
        }

        if (PhoneNumberValidator.isValidPhoneNumber(vo.getNickName())) {
            driverInfoMapper.updateSysUser(driverInfo);
            vo = driverInfoMapper.getDriverByPhone(phone,dataSource);
        }

        vo.setVehicleInfoList(vehicleInfoMapper.queryVehicleListByDriverByPhone(phone));
        vo.setVehicleCnt(driverInfoMapper.getsetVehicleCntByPhone(phone));

        if(null == vo.getIdCardInfo()){
            vo.setIdCardInfo( driverInfoMapper.querySysIdCardInfoById(vo.getLicenseNo()) );
        }

        if("1".equals(vo.getGender() ) || vo.getGender().contains("男")){
            vo.setGender("男");
        }else {
            vo.setGender("女");
        }
        return vo;
    }


    @Override
    public DriverInfoVo getDriverBylicenseOrIdcard(String licenseNo) {
        List<DriverInfoVo> driverBylicenseOrIdcardList = driverInfoMapper.getDriverBylicenseOrIdcard(licenseNo);
        List<DriverInfoVo> tempList = driverBylicenseOrIdcardList;
        if (tempList.size() > 1) {
            tempList = tempList.stream()
                    .filter(driver -> StringUtils.isNotBlank(driver.getDriverLicenseImg()))
                    .collect(Collectors.toList());
        }
        // 判断是否包含 dataSource = 11 的数据
        boolean hasDataSource11 = tempList.stream()
                .anyMatch(driver -> "实时物流小程序".equals(driver.getDataSource())); // 如果 dataSource 是字符串

        if (hasDataSource11) {
            tempList = tempList.stream()
                    .filter(driver -> "实时物流小程序".equals(driver.getDataSource()))
                    .collect(Collectors.toList());
        }
        if (tempList.isEmpty()) {
            tempList = driverBylicenseOrIdcardList;
        }

        DriverInfoVo po = tempList.get(0);
        if (StringUtils.isNotEmpty(po.getDriverLicenseImg())) {
            po.setRealName(true);
        }

        //            更新图片操作
        if (StringUtils.isEmpty(po.getDriverLicenseImg())) {
            driverInfoMapper.updateDriverBylicenseImg(licenseNo);
        }

        return po;
    }

    @Override
    public List<DriverInfo> importInfo(MultipartFile file, String sheetName, int rowNum) throws Exception {
        byte[] fileBytes = file.getBytes();
        List<DriverInfo> invoiceRecyclingInfos = ExcelUtil.readExcel(fileBytes, DriverInfo.class, sheetName, rowNum);
        return invoiceRecyclingInfos;
    }

    @Override
    public int bachSave(List<DriverInfo> dtoList) {
        int saveBatch = 0;
        List<DriverInfo> newList=new ArrayList<>();
        if (!dtoList.isEmpty()) {
            for (DriverInfo po : dtoList) {
                if (StringUtils.isNotEmpty(po.getLicenseNo()) && StringUtils.isNotEmpty(po.getPhoneNo())) {
                    po.setDataSource("四流平台");
//                    多个公司 看自己的司机
                    po.setId(MD5Utils.md5(po.getLicenseNo() + po.getPhoneNo() + po.getDataSource()+po.getOrgCode()));
                    po.setCreateUser(SecurityUtils.getUsername());
                    po.setCreateDate(DateUtils.getCurrentTime());
                    po.setViewFlag(true);
                    newList.add(po );
                }
            }


//            String[] arr = dtoList.stream()
//                    .map(DriverInfo::getLicenseNo) // 提取出 invoiceNum
//                    .distinct()                        // 去重
//                    .toArray(String[]::new);

//             导入之前 先删除
//            driverInfoMapper.batchDelete(arr);

            saveBatch = driverInfoMapper.batchSave(newList);
        }
        return saveBatch;
    }

    @Override
    public int flushDriverVehicleRef() {
        int result = driverInfoMapper.flushDriverVehicleRef();
        return result;
    }

    @Override
    public DriverInfoVo getDriverByPlateNo(String plateNo) {
        return driverInfoMapper.getDriverByPlateNo(plateNo);
    }

    @Override
    public List<DriverInfoVo> wechatList(DriverInfoDto driverInfo) {
        List<DriverInfoVo> driverInfoVos = driverInfoMapper.wechatList(driverInfo);
        for (DriverInfoVo vo : driverInfoVos) {
//            一个司机应该是有多个车
            List<VehicleInfo> vehicleInfos1 = vehicleInfoMapper.queryVehicleListByDriverByPhone(vo.getPhoneNo());
            List<VehicleInfo> vehicleInfos2 = vehicleInfoMapper.queryVehicleListByDriverByLicenseNo(vo.getLicenseNo());

// 处理空值
            vehicleInfos1 = vehicleInfos1 != null ? vehicleInfos1 : new ArrayList<>();
            vehicleInfos2 = vehicleInfos2 != null ? vehicleInfos2 : new ArrayList<>();

// 简单合并（不去重）
            List<VehicleInfo> mergedList = new ArrayList<>();

            if (vehicleInfos2.isEmpty()) {
                mergedList.addAll(vehicleInfos1);
            }
            mergedList.addAll(vehicleInfos2);

/*
// 如果需要去重
            List<VehicleInfo> mergedList = mergedList.stream()
                    .filter(Objects::nonNull)
                    .filter(vehicle -> vehicle.getId() != null)
                    .collect(Collectors.collectingAndThen(
                            Collectors.toMap(
                                    VehicleInfo::getId,
                                    Function.identity(),
                                    (existing, replacement) -> existing, // 如果ID重复，保留已有的
                                    LinkedHashMap::new
                            ),
                            map -> new ArrayList<>(map.values())
                    ));
*/


/*            if (mergedList != null && !mergedList.isEmpty()) {
                mergedList = mergedList.stream()
                        .filter(v -> {
                            if (v == null) {
                                // Skip null elements (return false to exclude them)
                                return false;
                            } else {

                                String plateNo = v.getPlateNo();
                                return plateNo != null && !plateNo.trim().isEmpty();
                            }
                        })
                        .collect(Collectors.toList());
            }*/

            if (mergedList == null || mergedList.isEmpty()) {
                mergedList = vehicleInfoMapper.queryVehicleListByDriverPhoneOrIdOther(vo.getPhoneNo());
            }
            if (mergedList != null && !mergedList.isEmpty()) {
/*
                // 使用 Optional 避免 NullPointerException
                mergedList = Optional.ofNullable(mergedList)
                        .orElseGet(Collections::emptyList)
                        .stream()
                        .filter(vehicleInfo -> vehicleInfo != null
                                && vehicleInfo.getPlateNo() != null
                                && !vehicleInfo.getPlateNo().isEmpty())
                        .collect(Collectors.collectingAndThen(
                                Collectors.toMap(
                                        VehicleInfo::getId,    // 用 id 作为 key
                                        Function.identity(),   // 保留当前对象
                                        (existing, replacement) -> existing // 如果有重复 id，保留第一个
                                ),
                                map -> new ArrayList<>(map.values()) // 转成 List
                        ));
*/

                if (mergedList != null && mergedList.size() > 0) {
                    vo.setVehicleInfoList(mergedList);
                } else {
                    vo.setVehicleInfoList(null);
                }
            } else {
                vo.setVehicleInfoList(null);
            }
        }

        return driverInfoVos;
    }

    @Override
    public int updateDriver(DriverInfo info) {
        int result = driverInfoMapper.updateDriver(info);
        return result;
    }

    @Override
    public int bind(DriverVehicleRef ref) {
//是靠phone 和plate 发生关系
//        DriverVehicleRef ref3= driverInfoMapper.findDriverVehicleRefByPhone(ref.getPhone()  ,ref.getPlateNo());
        DriverInfoVo vo = driverInfoMapper.getDriverByPhone(ref.getPhone(),"小程序");

        ref.setLicenseNo(vo.getLicenseNo());
//        要先查找有没有 ，
        DriverVehicleRef ref2 = driverInfoMapper.findDriverVehicleRefById(ref.getLicenseNo(), ref.getPlateNo());
//        统一id
        ref.setId(MD5Utils.md5(ref.getLicenseNo() + ref.getPlateNo()));

        if (ref2 == null) {
            driverInfoMapper.bind(ref);
        } else {
//        if(ref.getBind()){
            ref.setCreateDate(DateUtils.getCurrentTime());
            int result = driverInfoMapper.bind(ref);
            result = driverInfoMapper.updateDriverVehicleRefBind(ref);
        }


//        不只是要增加一条关系数据，车辆里面的电话号码也要更新
//        }else {
////            driverInfoMapper.deleteDriverInfoById()
//        }

        return 1;
    }

    @Override
    public int deleteBind(DriverVehicleRef info) {
        String id = MD5Utils.md5(info.getLicenseNo() + info.getPlateNo());

        return driverInfoMapper.deleteDriverVehicleRefByIds(new String[]{id});
    }

    @Override
    public int approve(String[] ids, String dataStatus) {
        return driverInfoMapper.approve(ids, dataStatus);
    }


}
